package com.goldsprite.gesturerecognizer;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.goldsprite.gesturerecognizer.core.Gesture;
import com.goldsprite.gesturerecognizer.core.GesturePoint;
import com.goldsprite.gesturerecognizer.core.GestureRecognizer;
import com.goldsprite.nfightgame.assets.GlobalAssets;

import java.util.ArrayList;

public class GestureDemo extends ApplicationAdapter {
	private ShapeRenderer shapeRenderer;
	private GestureRecognizer recognizer;
	private ArrayList<Gesture> templateGestures;
	private Gesture currentTemplateGesture;
	private Gesture userGesture;
	private boolean isMatching;
	private Color matchColor;

	// UI components
	private Stage stage;
	private FitViewport viewport;
	private Skin editorSkin;
	private BitmapFont titleFont;
	private BitmapFont normalFont;
	private BitmapFont smallFont;
	private Label statusLabel;
	private Label targetLabel;
	private List<String> gestureList;

	// 区域定义
	private float uiPanelWidth = 280;
	private float templateAreaX;
	private float drawingAreaX;
	private float areaWidth;
	private float screenHeight;
	private float screenWidth;
	private float worldHeight;

	@Override
	public void create() {
		shapeRenderer = new ShapeRenderer();
		recognizer = new GestureRecognizer();
		templateGestures = new ArrayList<>();
		matchColor = Color.GRAY;
		isMatching = false;

		// 初始化UI资源
		initializeUIAssets();

		// 初始化UI
		initializeUI();

		// 初始化区域参数
		screenWidth = Gdx.graphics.getWidth();
		screenHeight = Gdx.graphics.getHeight();
		updateAreas();

		// 创建多个预设手势
		createTemplateGestures();

		// 设置默认目标手势
		if (!templateGestures.isEmpty()) {
			currentTemplateGesture = templateGestures.get(0);
			updateGestureListSelection();
			updateTargetLabel();
		}

		Gdx.app.log("GestureDemo", "Initialized with " + templateGestures.size() + " template gestures");
	}

	private void initializeUIAssets() {
		// 使用 GlobalAssets 获取 editorSkin 和字体
		GlobalAssets globalAssets = GlobalAssets.getInstance();
		editorSkin = globalAssets.editorSkin;
		titleFont = globalAssets.editorFont;
		normalFont = globalAssets.editorFont;
		smallFont = globalAssets.smallFont;
	}

	private void initializeUI() {
		viewport = new com.badlogic.gdx.utils.viewport.FitViewport(1580, 720); // 设置一个基准分辨率
		viewport.apply();
		worldHeight = viewport.getWorldHeight();
		stage = new Stage(viewport);
		Gdx.input.setInputProcessor(stage);

		// 创建自定义Label样式
		Label.LabelStyle titleStyle = new Label.LabelStyle();
		titleStyle.font = titleFont;
		titleStyle.fontColor = Color.WHITE;

		Label.LabelStyle normalStyle = new Label.LabelStyle();
		normalStyle.font = normalFont;
		normalStyle.fontColor = Color.WHITE;

		Label.LabelStyle smallStyle = new Label.LabelStyle();
		smallStyle.font = smallFont;
		smallStyle.fontColor = Color.LIGHT_GRAY;

		// 创建主表格
		Table mainTable = new Table();
		mainTable.setFillParent(true);
		mainTable.left().top();
		mainTable.pad(15);
		mainTable.defaults().pad(5);

		// 标题
		Label titleLabel = new Label("手势识别演示", titleStyle);
		mainTable.add(titleLabel).left().padBottom(20).colspan(2);
		mainTable.row();

		// 目标手势显示
		targetLabel = new Label("目标: V字形", normalStyle);
		mainTable.add(targetLabel).left().colspan(2);
		mainTable.row();

		// 分隔线
		mainTable.add().height(1).colspan(2).pad(10, 0, 10, 0).fillX();
		mainTable.row();

		// 手势列表标签
		Label listLabel = new Label("选择目标手势:", normalStyle);
		mainTable.add(listLabel).left().colspan(2);
		mainTable.row();

		// 手势列表
		gestureList = new List<>(editorSkin);
		gestureList.setStyle(createListStyle(normalStyle));

		ScrollPane scrollPane = new ScrollPane(gestureList, editorSkin);
		scrollPane.setFadeScrollBars(false);
		scrollPane.setScrollbarsVisible(true);
		mainTable.add(scrollPane).width(250).height(150).colspan(2).padBottom(15);
		mainTable.row();

		// 状态显示
		statusLabel = new Label("状态: 准备就绪", normalStyle);
		mainTable.add(statusLabel).left().colspan(2).padBottom(15);
		mainTable.row();

		// 按钮行
		Table buttonTable = new Table();
		buttonTable.defaults().pad(2).width(120).height(40);

		TextButton clearButton = new TextButton("清除绘制", editorSkin);
		clearButton.getLabel().setStyle(normalStyle);
		clearButton.addListener(new com.badlogic.gdx.scenes.scene2d.utils.ClickListener() {
			@Override
			public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) {
				clearUserGesture();
			}
		});

		TextButton testButton = new TextButton("测试匹配", editorSkin);
		testButton.getLabel().setStyle(normalStyle);
		testButton.addListener(new com.badlogic.gdx.scenes.scene2d.utils.ClickListener() {
			@Override
			public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) {
				testGestureMatch();
			}
		});

		buttonTable.add(clearButton).padRight(5);
		buttonTable.add(testButton).padLeft(5);

		mainTable.add(buttonTable).colspan(2).center().padBottom(20);
		mainTable.row();

		// 使用说明
		Label instructionTitle = new Label("使用说明:", normalStyle);
		mainTable.add(instructionTitle).left().colspan(2).padBottom(5);
		mainTable.row();

		String instructions = "1. 从列表选择目标手势\n" +
			"2. 在右侧区域绘制手势\n" +
			"3. 抬起手指自动匹配\n" +
			"4. 绿色=匹配成功\n" +
			"   红色=匹配失败";

		Label instructionLabel = new Label(instructions, smallStyle);
		instructionLabel.setAlignment(Align.topLeft);
		mainTable.add(instructionLabel).left().colspan(2).width(250);

		stage.addActor(mainTable);
	}

	private List.ListStyle createListStyle(Label.LabelStyle labelStyle) {
		List.ListStyle listStyle = new List.ListStyle();
		listStyle.font = labelStyle.font;
		listStyle.fontColorSelected = Color.YELLOW;
		listStyle.fontColorUnselected = Color.WHITE;
		listStyle.selection = editorSkin.getDrawable("list-selection");
		return listStyle;
	}

	private void createTemplateGestures() {
		templateGestures.clear();
		recognizer = new GestureRecognizer();

		float centerX = templateAreaX + areaWidth / 2f;
		float centerY = worldHeight / 2f;
		float size = Math.min(areaWidth, screenHeight) * 0.2f;

		// 手势1: V字形
		Gesture vGesture = new Gesture("V字形");
		vGesture.addPoint(new GesturePoint(centerX - size, centerY + size));
		vGesture.addPoint(new GesturePoint(centerX, centerY - size));
		vGesture.addPoint(new GesturePoint(centerX + size, centerY + size));
		templateGestures.add(vGesture);
		recognizer.addGestureToLibrary("V字形", vGesture);

		// 手势2: 圆形
		Gesture circleGesture = new Gesture("圆形");
		int circlePoints = 16;
		for (int i = 0; i < circlePoints; i++) {
			float angle = (float) (2 * Math.PI * i / circlePoints);
			float x = centerX + size * (float) Math.cos(angle);
			float y = centerY + size * (float) Math.sin(angle);
			circleGesture.addPoint(new GesturePoint(x, y));
		}
		templateGestures.add(circleGesture);
		recognizer.addGestureToLibrary("圆形", circleGesture);

		// 手势3: 三角形
		Gesture triangleGesture = new Gesture("三角形");
		triangleGesture.addPoint(new GesturePoint(centerX, centerY + size));
		triangleGesture.addPoint(new GesturePoint(centerX - size, centerY - size));
		triangleGesture.addPoint(new GesturePoint(centerX + size, centerY - size));
		triangleGesture.addPoint(new GesturePoint(centerX, centerY + size));
		templateGestures.add(triangleGesture);
		recognizer.addGestureToLibrary("三角形", triangleGesture);

		// 手势4: 正方形
		Gesture squareGesture = new Gesture("正方形");
		squareGesture.addPoint(new GesturePoint(centerX - size, centerY - size));
		squareGesture.addPoint(new GesturePoint(centerX - size, centerY + size));
		squareGesture.addPoint(new GesturePoint(centerX + size, centerY + size));
		squareGesture.addPoint(new GesturePoint(centerX + size, centerY - size));
		squareGesture.addPoint(new GesturePoint(centerX - size, centerY - size));
		templateGestures.add(squareGesture);
		recognizer.addGestureToLibrary("正方形", squareGesture);

		// 手势5: 心形
		Gesture heartGesture = new Gesture("心形");
		int heartPoints = 20;
		for (int i = 0; i < heartPoints; i++) {
			float t = (float) i / (heartPoints - 1);
			float angle = (float) (2 * Math.PI * t);
			float x = centerX + size * (float) (16 * Math.pow(Math.sin(angle), 3));
			float y = centerY + size * (float) (13 * Math.cos(angle) - 5 * Math.cos(2*angle) - 2 * Math.cos(3*angle) - Math.cos(4*angle));
			heartGesture.addPoint(new GesturePoint(x, y/16));
		}
		templateGestures.add(heartGesture);
		recognizer.addGestureToLibrary("心形", heartGesture);

		// 更新列表
		if (gestureList != null) {
			gestureList.setItems(getGestureNames());
		}
	}

	private String[] getGestureNames() {
		ArrayList<String> names = new ArrayList<>();
		for (Gesture gesture : templateGestures) {
			names.add(gesture.getName());
		}
		return names.toArray(new String[0]);
	}

	private void updateGestureListSelection() {
		if (currentTemplateGesture != null && gestureList != null) {
			String[] names = getGestureNames();
			for (int i = 0; i < names.length; i++) {
				if (names[i].equals(currentTemplateGesture.getName())) {
					gestureList.setSelectedIndex(i);
					break;
				}
			}
		}
	}

	private void updateTargetLabel() {
		if (targetLabel != null && currentTemplateGesture != null) {
			targetLabel.setText("目标: " + currentTemplateGesture.getName());
		}
	}

	@Override
	public void render() {
		Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		handleInput();
		draw();
		stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
		stage.draw();

		if (isMatching && userGesture != null && currentTemplateGesture != null) {
			boolean match = recognizer.matchGestures(currentTemplateGesture, userGesture);
			matchColor = match ? Color.GREEN : Color.RED;
			statusLabel.setText("状态: " + (match ? "匹配成功!" : "匹配失败!"));
			isMatching = false;
		}

		// 检查手势列表选择变化
		String selected = gestureList.getSelected();
		if (selected != null && currentTemplateGesture != null &&
			!selected.equals(currentTemplateGesture.getName())) {
			for (Gesture gesture : templateGestures) {
				if (gesture.getName().equals(selected)) {
					currentTemplateGesture = gesture;
					clearUserGesture();
					updateTargetLabel();
					statusLabel.setText("状态: 已选择 " + selected);
					break;
				}
			}
		}
	}

	private void handleInput() {
		stage.act();

		if (Gdx.input.justTouched()) {
			float x = Gdx.input.getX();
			float y = Gdx.graphics.getHeight() - Gdx.input.getY();

			if (x >= drawingAreaX && x <= screenWidth) {
				if (!isPointInUI(x, y)) {
					userGesture = null;
					matchColor = Color.GRAY;
					isMatching = false;
					statusLabel.setText("状态: 正在绘制...");

					recognizer.startRecording("UserGesture");
					recognizer.addPoint(x, y);
				}
			}
		}

		if (Gdx.input.isTouched() && recognizer.isRecording()) {
			float x = Gdx.input.getX();
			float y = Gdx.graphics.getHeight() - Gdx.input.getY();

			if (x >= drawingAreaX && x <= screenWidth && !isPointInUI(x, y)) {
				recognizer.addPoint(x, y);
			}
		}

		if (!Gdx.input.isTouched() && recognizer.isRecording()) {
			userGesture = recognizer.finishRecording();
			if (userGesture != null && userGesture.getPointCount() > 1) {
				statusLabel.setText("状态: 正在匹配...");
				isMatching = true;
			} else {
				statusLabel.setText("状态: 绘制手势过短");
			}
		}
	}

	private boolean isPointInUI(float x, float y) {
		return x < uiPanelWidth;
	}

	private void clearUserGesture() {
		userGesture = null;
		matchColor = Color.GRAY;
		isMatching = false;
		statusLabel.setText("状态: 已清除绘制");
	}

	private void testGestureMatch() {
		if (userGesture != null && currentTemplateGesture != null) {
			boolean match = recognizer.matchGestures(currentTemplateGesture, userGesture);
			matchColor = match ? Color.GREEN : Color.RED;
			statusLabel.setText("状态: " + (match ? "测试匹配成功!" : "测试匹配失败!"));
		} else {
			statusLabel.setText("状态: 请先绘制手势");
		}
	}

	private void updateAreas() {
		areaWidth = (worldHeight - uiPanelWidth) / 2f;
		templateAreaX = uiPanelWidth;
		drawingAreaX = uiPanelWidth + areaWidth;
	}

	private void draw() {
		// 绘制背景区域
		shapeRenderer.begin(ShapeType.Filled);

		// 绘制UI面板背景
		shapeRenderer.setColor(new Color(0.12f, 0.12f, 0.18f, 1f));
		shapeRenderer.rect(0, 0, uiPanelWidth, worldHeight);

		// 绘制左侧模板区域
		shapeRenderer.setColor(new Color(0.25f, 0.25f, 0.35f, 1f));
		shapeRenderer.rect(templateAreaX, 0, areaWidth, worldHeight);

		// 绘制右侧绘制区域
		shapeRenderer.setColor(new Color(0.35f, 0.35f, 0.45f, 1f));
		shapeRenderer.rect(drawingAreaX, 0, areaWidth, worldHeight);

		shapeRenderer.end();

		// 绘制手势点和连线
		drawGestures();

		// 绘制区域标签
		drawAreaLabels();
	}

	private void drawAreaLabels() {
		stage.getBatch().begin();

		BitmapFont font = normalFont;
		font.setColor(Color.WHITE);

		// 模板区域标签
		String templateText = "模板区域";
		float templateTextWidth = getTextWidth(font, templateText);
		font.draw(stage.getBatch(), templateText,
			templateAreaX + areaWidth/2 - templateTextWidth/2, worldHeight - 30);

		// 绘制区域标签
		String drawText = "绘制区域";
		float drawTextWidth = getTextWidth(font, drawText);
		font.draw(stage.getBatch(), drawText,
			drawingAreaX + areaWidth/2 - drawTextWidth/2, worldHeight - 30);

		stage.getBatch().end();
	}

	private float getTextWidth(BitmapFont font, String text) {
		com.badlogic.gdx.graphics.g2d.GlyphLayout layout = new com.badlogic.gdx.graphics.g2d.GlyphLayout();
		layout.setText(font, text);
		return layout.width;
	}

	private void drawGestures() {
		// 绘制当前目标手势（左侧）
		if (currentTemplateGesture != null && currentTemplateGesture.getPointCount() > 0) {
			// 绘制点
			shapeRenderer.begin(ShapeType.Filled);
			shapeRenderer.setColor(Color.CYAN);
			for (GesturePoint point : currentTemplateGesture.getPoints()) {
				shapeRenderer.circle(point.x, point.y, 6);
			}
			shapeRenderer.end();

			// 绘制连线
			shapeRenderer.begin(ShapeType.Line);
			shapeRenderer.setColor(new Color(0.7f, 1f, 1f, 1f));
			for (int i = 0; i < currentTemplateGesture.getPointCount() - 1; i++) {
				GesturePoint p1 = currentTemplateGesture.getPoint(i);
				GesturePoint p2 = currentTemplateGesture.getPoint(i + 1);
				shapeRenderer.line(p1.x, p1.y, p2.x, p2.y);
			}
			shapeRenderer.end();
		}

		// 绘制用户手势（右侧）
		if (userGesture != null && userGesture.getPointCount() > 0) {
			// 绘制点
			shapeRenderer.begin(ShapeType.Filled);
			shapeRenderer.setColor(matchColor);
			for (GesturePoint point : userGesture.getPoints()) {
				shapeRenderer.circle(point.x, point.y, 6);
			}
			shapeRenderer.end();

			// 绘制连线
			shapeRenderer.begin(ShapeType.Line);
			shapeRenderer.setColor(matchColor);
			for (int i = 0; i < userGesture.getPointCount() - 1; i++) {
				GesturePoint p1 = userGesture.getPoint(i);
				GesturePoint p2 = userGesture.getPoint(i + 1);
				shapeRenderer.line(p1.x, p1.y, p2.x, p2.y);
			}
			shapeRenderer.end();
		}

		// 绘制录制中的手势（右侧）
		if (recognizer.isRecording()) {
			Gesture current = recognizer.getCurrentGesture();
			if (current != null && current.getPointCount() > 0) {
				// 绘制点
				shapeRenderer.begin(ShapeType.Filled);
				shapeRenderer.setColor(Color.YELLOW);
				for (GesturePoint point : current.getPoints()) {
					shapeRenderer.circle(point.x, point.y, 4);
				}
				shapeRenderer.end();

				// 绘制连线
				shapeRenderer.begin(ShapeType.Line);
				shapeRenderer.setColor(Color.YELLOW);
				for (int i = 0; i < current.getPointCount() - 1; i++) {
					GesturePoint p1 = current.getPoint(i);
					GesturePoint p2 = current.getPoint(i + 1);
					shapeRenderer.line(p1.x, p1.y, p2.x, p2.y);
				}
				shapeRenderer.end();
			}
		}
	}

	@Override
	public void resize(int width, int height) {
		screenWidth = width;
		screenHeight = height;
		worldHeight = height;
		updateAreas();

		viewport.update(width, height, true);

		// 重新创建模板手势以适应新尺寸
		createTemplateGestures();
		if (!templateGestures.isEmpty() && currentTemplateGesture != null) {
			for (Gesture gesture : templateGestures) {
				if (gesture.getName().equals(currentTemplateGesture.getName())) {
					currentTemplateGesture = gesture;
					break;
				}
			}
			updateTargetLabel();
		}
	}

	@Override
	public void dispose() {
		shapeRenderer.dispose();
		stage.dispose();
		// 注意：不要dispose editorSkin，因为它由GlobalAssets管理
	}
}

